import xmlrpclib
from common_data import *
from permission import *
from xmlrpc_environment_resource import XMLRPC_EnvironmentResource
from xmlrpc_user_resource import XMLRPC_UserResource
from xmlrpc_party_resource import XMLRPC_PartyResource
from xmlrpc_resource_record_resource import XMLRPC_ResourceRecordResource
from xmlrpc_checkout_resource import XMLRPC_CheckoutResource
from xmlrpc_dns_server_config import XMLRPC_DNSServerConfig
from xmlrpc_xmlrpc_server_config import XMLRPC_XMLRPCServerConfig
from twisted.web import xmlrpc, http, server
from twisted.python import log
from twisted.internet import defer

class XMLRPC_BaseResource( xmlrpc.XMLRPC,
                           xmlrpc.XMLRPCIntrospection, 
                           XMLRPC_EnvironmentResource, 
                           XMLRPC_UserResource,
                           XMLRPC_PartyResource, 
                           XMLRPC_ResourceRecordResource, 
                           XMLRPC_CheckoutResource,
                           XMLRPC_DNSServerConfig, 
                           XMLRPC_XMLRPCServerConfig, ):
    permissions = {}
    
    def __init__(self):
        """ load config
        """
        log.msg( 'Base resource init' )
        
        self.permissions = {}
        
        xmlrpc.XMLRPC.__init__(self)
        
        XMLRPC_EnvironmentResource.__init__(self)
        self.registerPermissions( XMLRPC_EnvironmentResource._permissions )
        
        XMLRPC_ResourceRecordResource.__init__(self)
        self.registerPermissions( XMLRPC_ResourceRecordResource._permissions )
        
        XMLRPC_CheckoutResource.__init__(self)
        self.registerPermissions( XMLRPC_CheckoutResource._permissions )
        
        XMLRPC_UserResource.__init__(self)
        self.registerPermissions( XMLRPC_UserResource._permissions )

        XMLRPC_PartyResource.__init__(self)
        self.registerPermissions( XMLRPC_PartyResource._permissions )

        XMLRPC_DNSServerConfig.__init__(self)
        self.registerPermissions( XMLRPC_DNSServerConfig._permissions )
                
        XMLRPC_XMLRPCServerConfig.__init__(self)
        self.registerPermissions( XMLRPC_XMLRPCServerConfig._permissions )
        
        xmlrpc.XMLRPCIntrospection.__init__(self, self)
        
        # give global permissions to introspection methods
        self.permissions.update( { 
            'listMethods': PERMISSION_REQUIREMENT_GLOBAL_USER, 
            'methodSignature': PERMISSION_REQUIREMENT_GLOBAL_USER,
            'methodHelp': PERMISSION_REQUIREMENT_GLOBAL_USER } )
        
#        xmlrpc.addIntrospection( self )
        
    def render(self, request):
        
        user_name = request.getUser()
        password = request.getPassword()
        
        if user_name is '' or password is '':
            log.err( 'call received without authentication' )
            request.setResponseCode( http.UNAUTHORIZED )
            return 'unable to authenticate'
        
        try:
            user = User.selectBy( name = str( user_name ) ).getOne()
        except SQLObjectNotFound:
            log.err( 'invalid user authentication attempt: user = %s' % str( user_name ) )
            request.setResponseCode( http.UNAUTHORIZED )
            return 'unable to authenticate'
        except:
            log.err( 'could not retrieve user. user_name: %s' % str( user_name ) )
            log.err()
            request.setResponseCode( http.UNAUTHORIZED )
            return 'unable to authenticate'
                    
        if user.password != password:
            log.err( 'invalid authentication: user = %s, password = %s' % ( str( user_name ), str( password ) ) )
            request.setResponseCode( http.UNAUTHORIZED )
            return 'unable to authenticate'

        request.content.seek(0, 0)
        args, functionPath = xmlrpclib.loads(request.content.read())
        
        """ check permissions """
        if not str( functionPath ) in self.permissions:
            log.err( 'call to a method without registered permissions %s' % functionPath )
            request.setResponseCode( http.NOT_IMPLEMENTED )
            return 'unable to grant permissions'
        
        try:
            validateUser( self.permissions[ functionPath ], user, *args )
        except PermissionExceptionUnauthorized, data:
            request.setResponseCode( http.UNAUTHORIZED )
            return '%s' % data
        except PermissionException, data:
            log.err( 'could not validate user: method: %s, msg: %s ' % ( functionPath , data ) )
            request.setResponseCode( http.INTERNAL_SERVER_ERROR )
            return 'unable to grant permissions'
                
        return xmlrpc.XMLRPC.render(self, request)
    
    def registerPermissions(self, perms ):
        if not len( perms ):
            log.err( 'could not register resource permissions' )
            raise Exception( 'could not register resource permissions' )
        
        self.permissions.update( perms )